package service.jsoft.com;

import com.google.appengine.api.datastore.*;

import dao.jsoft.com.PMF;
import domain.jsoft.com.AppRole;
import domain.jsoft.com.GaeUser;
import domain.jsoft.com.User;

import org.springframework.security.core.GrantedAuthority;
import java.util.*;

import javax.jdo.PersistenceManager;

public class GaeDatastoreUserRegistry implements UserRegistry {
    private static final String USER_TYPE = "GaeUser";
    private static final String USER_FIRSTNAME = "firstname";
    private static final String USER_LASTNAME = "lastname";
    private static final String USER_NICKNAME = "nickname";
    private static final String USER_EMAIL = "email";
    private static final String USER_ENABLED = "enabled";
    private static final String USER_AUTHORITIES = "authorities";

    public GaeUser findUser(String userId) {
    	/*PersistenceManager pm = PMF.get().getPersistenceManager(); 
        GaeUser user = pm.getObjectById(GaeUser.class, userId);
        
        if (user == null){ //Not found
        	 System.out.println(userId + " not found in datastore");
             return null;
        }
        else {
        	return user;
        }
        
        */
        Key key = KeyFactory.createKey(USER_TYPE, userId); 
        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

        try {
            Entity user = datastore.get(key);

            long binaryAuthorities = (Long)user.getProperty(USER_AUTHORITIES);
            Set<AppRole> roles = EnumSet.noneOf(AppRole.class);

            for (AppRole r : AppRole.values()) {
                if ((binaryAuthorities & (1 << r.getBit())) != 0) {
                    roles.add(r);
                }
            }

            GaeUser gaeUser = new GaeUser(
                    user.getKey().getName(),
                    (String)user.getProperty(USER_NICKNAME),
                    (String)user.getProperty(USER_EMAIL),
                    (String)user.getProperty(USER_FIRSTNAME),
                    (String)user.getProperty(USER_LASTNAME),
                    roles,
                    (Boolean)user.getProperty(USER_ENABLED));

            return gaeUser;

        } catch (EntityNotFoundException e) {
            System.out.println(userId + " not found in datastore");
            return null;
        }
        
    }

    public void registerUser(GaeUser newUser) {
    	
        Key key = KeyFactory.createKey(USER_TYPE, newUser.getUserId());
        Entity user = new Entity(key);
        user.setProperty(USER_EMAIL, newUser.getEmail());
        user.setProperty(USER_NICKNAME, newUser.getNickname());
        user.setProperty(USER_FIRSTNAME, newUser.getFirstname());
        user.setProperty(USER_LASTNAME, newUser.getLastname());
        user.setUnindexedProperty(USER_ENABLED, newUser.isEnabled());

        Collection<? extends GrantedAuthority> roles = newUser.getRoles();

        long binaryAuthorities = 0;

        for (GrantedAuthority r : roles) {
            binaryAuthorities |= 1 << ((AppRole)r).getBit();
        }

        user.setUnindexedProperty(USER_AUTHORITIES, binaryAuthorities);

        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
        datastore.put(user); 
    	/*
    	PersistenceManager pm = PMF.get().getPersistenceManager();       
		GaeUser user = new GaeUser(newUser.getUserId(), newUser.getNickname(), newUser.getEmail(), newUser.getFirstname(), newUser.getLastname(), newUser.getAuthorities(), newUser.isEnabled());

		try {             
			pm.makePersistent(user);     
			pm.flush();
		} 
		finally {             
			pm.close();         
		}*/
    }

    public void removeUser(String userId) {
        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
        Key key = KeyFactory.createKey(USER_TYPE, userId);

        datastore.delete(key);
    }
}
